<template>
    <NScrollbar ref="scrollBarRef">
        <NList class="w-full delay-100 " id="chatLog">
            <NListItem
                v-for="(item, index) in chat.conversation"
                class="w-full"
                :id="'item' + index.toString()"
                :style="getStyle(props.theme)"
            >
                <div class="w-full rounded-md" v-load="item.loading">
                    <div >
                        <NH3 prefix="bar" :type="
                        layout[getLayout(item.target)].headType
                        ">
                            <NRow>
                                <NIcon :size="20" class="self-center">
                                    <div
                                        v-html="TargetIconDict[item.icon]"
                                    ></div>
                                </NIcon>
                                <div>
                                    {{ new Date(item.time).toLocaleString() }}
                                    &ensp; {{ item.target }}
                                </div>
                                <NTooltip trigger="hover">
                                    <template #trigger>
                                        <NButton
                                            text
                                            class="ml-4"
                                            @click="copyToClipboard(index)"
                                        >
                                            <NIcon :size="20"
                                                ><div v-html="FileCopyIcon"></div
                                            ></NIcon>
                                        </NButton>
                                    </template>
                                    <p>复制</p>
                                </NTooltip>
                                <NTooltip trigger="hover">
                                    <template #trigger>
                                        <NButton
                                            :disabled="props.disabled"
                                            text
                                            class="ml-2"
                                            @click="deleteConversation(index)"
                                        >
                                            <NIcon :size="20"
                                                ><div v-html="FileExcelIcon"></div
                                            ></NIcon>
                                        </NButton>
                                    </template>
                                    <p>删除</p>
                                </NTooltip>
                                <NTooltip v-if="getLayout(item.target)=='left'">
                                    <template #trigger trigger="hover">
                                        <NButton
                                            :disabled="props.disabled"
                                            text
                                            class="ml-2"
                                            @click="emits('reload', index)"
                                        >
                                            <NIcon :size="20">
                                                <div v-html="ReloadIcon"></div>
                                            </NIcon>
                                        </NButton>
                                    </template>
                                    <p>重载</p>
                                </NTooltip>
                            </NRow>
                        </NH3>
                    </div>
                    <NRow>
                        <NThing content-style="margin-top: 10px w-full">
                            <template #description>
                                <div class="w-full">
                                    <NRow class="flex self-center"> </NRow>
                                    <NRow>
                                        <MdEditor
                                            class="ml-4 mr-4"
                                            preview-only
                                            :model-value="codeSmooth(item.content)"
                                            :theme="props.theme"
                                            :code-theme="'default'"
                                            :style="getStyle(props.theme)"
                                        >
                                        </MdEditor>
                                    </NRow>
                                </div>
                            </template>
                        </NThing>
                    </NRow>
                </div>
            </NListItem>
        </NList>
    </NScrollbar>
</template>
<script lang="ts" setup>
import { reactive, watch, Ref, ref } from "vue";
import {
    NTooltip,
    NThing,
    NList,
    NListItem,
    NScrollbar,
    NIcon,
    NRow,
    NButton,
    useMessage,
    NP,
    NH3,
NPopover,
} from "naive-ui";

import "md-editor-v3/lib/style.css";
import MdEditor from "md-editor-v3";
import ReloadIcon from "@/assets/icons/reload.svg";
import FileCopyIcon from "@/assets/icons/file-copy.svg";
import FileExcelIcon from "@/assets/icons/file-excel.svg";
import UserIcon from "@/assets/icons/UserOutlined.svg";
import AIIcon from "@/assets/icons/aislogo.svg";
import BrainIcon from "@/assets/icons/BrainCircuit20Regular.svg";

let TargetIconDict: { [key: string]: string } = reactive({
    UserOutlined: UserIcon,
    aislogo: AIIcon,
    BrainCircuit20Regular: BrainIcon,
});
const message = useMessage();
let scrollBarRef: Ref<HTMLDivElement> = ref(null) as any;
interface Props {
    conversation: Conversation[];
    rightTarget: string[];
    scrollToIndex: number;
    updateKey: any;
    disabled: boolean;
    theme: "dark" | "light";
}
interface Conversation {
    id: number;
    role: string;
    content: string;
    target: string; //gpt和me两个对象
    time: number;
    icon: string;
    loading: boolean;
}

const props = withDefaults(defineProps<Props>(), {
    conversation: () => [],
    rightTarget: () => ["我"],
    scrollToIndex: () => 0,
    key: () => 0,
    disabled: () => false,
    theme: () => "dark",
});
const emits = defineEmits<{
    (event: "update:conversation", value: Conversation[]): void;
    (event: "update:scollToIndex", value: number): void;
    (event: "reload", index: number): void;
}>();
let chat = reactive({
    conversation: [] as Conversation[],
    rightTarget: ["我"],
    scollToIndex: 0 as number,
    initialTime: new Date().getTime() as number,
    smooth:false
});
function getLayout(target:string):"right"|"left"{
    if(props.rightTarget.includes(target)){
        return 'right'
    }
    return 'left'
}
let layout:{[key:string]:any} = {
    left:{
        headType:"warning"
    },
    right:{
        headType:"primary"
    }
}
async function scollToTarget() {
    let chatItemNode = document.querySelector(
        `#chatLog #item${chat.scollToIndex}`
    ) as HTMLElement;
    if (chatItemNode != null) {
        scrollBarRef.value.scrollTo({
            top: chatItemNode.offsetTop + chatItemNode.offsetHeight - 300,
            behavior: "smooth",
        });
    }
}
function codeSmooth(text:string){
    if(chat.smooth){
        return text.replaceAll("`","").replaceAll("#","")
    }
    else{
        return text
    }
}
async function copyToClipboard(index: number) {
    navigator.clipboard
        .writeText(chat.conversation[index].content)
        .then(() => message.success("复制成功"))
        .catch(() => message.error("复制失败"));
}
async function deleteConversation(index: number) {
    chat.conversation.splice(index, 1);
    emits("update:conversation", chat.conversation);
    message.success("删除成功");
}
watch(
    () => props.conversation.length,
    () => {
        chat.scollToIndex = chat.conversation.length - 1;
        emits("update:scollToIndex", chat.scollToIndex);
    },
    { deep: true, immediate: true }
);

watch(
    () => props.updateKey,
    (value, preValue) => {
        chat.conversation = props.conversation;
        chat.smooth = true
        setTimeout(()=>{
            if(new Date().getTime()-chat.initialTime>1000){
                chat.smooth = false
            }
        },1000)
        if (new Date().getTime() - chat.initialTime > 500) {
            scollToTarget();
            chat.initialTime = new Date().getTime();
        }
    },
    { deep: true, immediate: true }
);
watch(
    () => props.scrollToIndex,
    (value, preValue) => {
        chat.scollToIndex = value;
    },
    { deep: true, immediate: true }
);
function getStyle(theme: "light" | "dark") {
    return {
        light: {
            "background-color": "rgb(220,220,220)",
            width: "100%",
        },
        dark: {},
    }[theme];
}
</script>
<style>
.md-editor {
}
.md-editor-dark {
    --md-bk-color: rgb(25, 25, 25) !important;
    --md-color: rgb(255, 255, 255);
}
</style>
